package com.camartsApp.controller;

import com.camartsApp.Util.AliyunOssUtil;
import com.camartsApp.service.UserService;
import com.camartsApp.Util.JwtUtils;
import com.camartsApp.Util.RedisUtil;
import com.camartsApp.Util.Response;
import com.camartsApp.common.ResultVO;
import com.camartsApp.entity.User;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.Objects;

/**
 * @version .......
 * @创建时间 2025/6/12  下午8:15
 * @创建者 玉苏甫江
 */
@RestController
@RequestMapping("/api/user")
public class UserController {

	@Autowired
	private UserService userService;
	@Autowired
	private JwtUtils jwtUtils;

	@Autowired
	private AliyunOssUtil aliyunOssUtil;

	@Autowired
	private RedisUtil redisUtil;

	/**
	 * 用户注册
	 */
	@PostMapping("/register")
	public ResultVO register(@RequestBody User user) {
		String result = userService.register(user);
		if ("注册成功".equals(result)) {
			return Response.OkByData(result);
		} else {
			return Response.FailResultByMsg(result);
		}
	}

	/**
	 * 用户登录
	 */
	@PostMapping("/login")
	public ResultVO login(@RequestBody User user) {
		String token = userService.login(user.getPhone(), user.getPassword());
		if ("手机号错误或不存在".equals(token) || "该账号已被封禁".equals(token) || "密码错误".equals(token)) {
			return Response.FailResultByMsg(token);
		}
		User userInfo = userService.getUserInfo(user.getPhone());
		return Response.OkByData(new LoginResp(userInfo, token));
	}


	/**
	 * 用户登出
	 */
	@PostMapping("/logout")
	public ResultVO logout(HttpServletRequest request) {
		String token = extractToken(request.getHeader("Authorization"));
		String phone = jwtUtils.getPhoneFromToken(token);
		userService.logout(phone);
		return Response.OkByMsg("登出成功");
	}

	/**
	 * 获取用户信息
	 */
	@GetMapping("/info")
	public ResultVO getUserInfo(HttpServletRequest request) {
		String token = extractToken(request.getHeader("Authorization"));
		String phone = jwtUtils.getPhoneFromToken(token);
		User user = userService.getUserInfo(phone);
		if (user != null) {
			user.setPassword(null);
		}
		return Response.OkByData(user);
	}

	@PostMapping("/avatar")
	public ResultVO uploadAvatar(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
		String token = extractToken(request.getHeader("Authorization"));
		String phone = jwtUtils.getPhoneFromToken(token);

		// 1. 上传到阿里云
		String avatarUrl = aliyunOssUtil.upload(file);

		// 2. 更新数据库
		boolean ok = userService.updateAvatar(phone, avatarUrl);
		if (ok) {
			return Response.OkByData(avatarUrl);
		}
		return Response.FailResultByMsg("头像上传失败");
	}

	/**
	 * 修改用户信息（只能改部分字段，phone为主键）
	 */
	@PutMapping("/update")
	public ResultVO updateUserInfo(@RequestBody User user, HttpServletRequest request) {
		// 强制保证只能修改自己的信息（防止前端绕过phone字段）
		String token = extractToken(request.getHeader("Authorization"));
		String phone = jwtUtils.getPhoneFromToken(token);
		user.setPhone(phone); // 保证phone为当前登录用户
		boolean ok = userService.updateUserInfo(user);
		if (ok) {
			User user1 = userService.getUserInfoByPhone(phone);
			user1.setPassword(null);
			return Response.OkByData(user1);
		}
		return Response.FailResultByMsg("修改失败");
	}

	/**
	 * 修改密码
	 */
	@PutMapping("/password")
	public ResultVO updatePassword(@RequestBody UpdatePasswordVO vo, HttpServletRequest request) {
		String token = extractToken(request.getHeader("Authorization"));
		String phone = jwtUtils.getPhoneFromToken(token);
		if (!Objects.equals(vo.getPhone(), phone)) {
			return Response.FailResultByMsg("手机号错误");
		}
		// 调用修改后的 userService.updatePassword，它现在返回 boolean
		boolean isSuccess = userService.updatePassword(phone, vo.getOldPassword(), vo.getNewPassword(), token);

		if (isSuccess) {
			return Response.OkByMsg("密码修改成功");
		} else {
			// 密码修改失败，可能原因：用户不存在、旧密码错误、数据库更新失败等
			return Response.FailResultByMsg("密码修改失败，请检查旧密码是否正确或账号是否存在。");
		}
	}

	/**
	 * 修改手机号
	 */
	@PutMapping("/phone")
	public ResultVO updatePhone(@RequestBody UpdatePhoneVO vo, HttpServletRequest request) {
		String token = extractToken(request.getHeader("Authorization"));
		String oldPhone = jwtUtils.getPhoneFromToken(token);
		if (!Objects.equals(vo.getPhone(), oldPhone)) {
			return Response.FailResultByMsg("手机号错误");
		}
		// 调用修改后的 userService.updatePhone，它现在返回 User 对象或 null
		User updatedUser = userService.updatePhone(oldPhone, vo.getPassword(), vo.getNewPhone(), token);

		if (updatedUser != null) {
			// 手机号修改成功
			String newRedisKey = "usert:" + vo.getNewPhone() + ":token";
			String newToken = redisUtil.get(newRedisKey);
			return Response.OkByData(new UpdatePhoneSuccessResp(updatedUser, newToken));
		} else {
			// 手机号修改失败，可能原因：新手机号已注册、密码错误、用户不存在等
			return Response.FailResultByMsg("手机号更改失败，请检查新手机号是否已被注册或密码是否正确。");
		}
	}

	/**
	 * 修改邮箱
	 */
	@PutMapping("/email")
	public ResultVO updateEmail(@RequestBody UpdateEmailVO vo, HttpServletRequest request) {
		String token = extractToken(request.getHeader("Authorization"));
		String oldPhone = jwtUtils.getPhoneFromToken(token);
		if (!Objects.equals(vo.getPhone(), oldPhone)) {
			return Response.FailResultByMsg("手机号错误");
		}
		// 调用修改后的 userService.updateEmail，它现在返回 boolean
		boolean isSuccess = userService.updateEmail(vo.getPhone(), vo.getPassword(), vo.getNewEmail());

		if (isSuccess) {
			return Response.OkByMsg("邮箱修改成功");
		} else {
			// 邮箱修改失败，可能原因：新邮箱不能为空、新邮箱已被注册、用户不存在、密码错误等
			return Response.FailResultByMsg("邮箱修改失败，请检查新邮箱是否已被注册、密码是否正确或手机号是否存在。");
		}
	}

	// ====================== DTO/VO 内部类 ======================

	@lombok.Setter
	@lombok.Getter
	public static class UpdateEmailVO {
		private String phone;
		private String password;
		private String newEmail;
	}

	/**
	 * 从Authorization头中提取Bearer token（如果有"Bearer "前缀，自动去除）
	 */
	private String extractToken(String authHeader) {
		if (authHeader == null || !authHeader.startsWith("Bearer ")) {
			return null;
		}
		return authHeader.substring(7);
	}

	@lombok.Getter
	public static class LoginResp {
		private final User user;
		private final String token;

		public LoginResp(User user, String token) {
			this.user = user;
			if (this.user != null) this.user.setPassword(null);
			this.token = token;
		}
	}

	@Setter
	@Getter
	public static class TokenResp {

		private  String phone;
		private final String token;
		public TokenResp(String token, String phone) { this.token = token;  this.phone = phone;}
	}

	@lombok.Setter
	@lombok.Getter
	public static class UpdatePasswordVO {
		private String phone;
		private String oldPassword;
		private String newPassword;
	}

	@lombok.Setter
	@lombok.Getter
	public static class UpdatePhoneVO {
		private String phone;
		private String password;
		private String newPhone;
	}

	@lombok.Getter
	public static class UpdatePhoneSuccessResp {
		private final User userInfo;
		private final String token;

		public UpdatePhoneSuccessResp(User userInfo, String token) {
			this.userInfo = userInfo;
			if (this.userInfo != null) this.userInfo.setPassword(null);
			this.token = token;
		}
	}
}